/*
Copyright (C) 2015 Marien Raat

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <random>
#include <fractalNoise.h>

// This class takes a heightmap, a water map, a land map, a heat map
// and a random generator and generates a groundWater map.  It uses the
// random generator to generate fractal noise. It then uses the
// height, the distance from the closest water and the heat to
// determine a groundWater at every position.
class GroundWaterMapGenerator {
public:
    GroundWaterMapGenerator(std::mt19937 *mt);

    // Generates a groundWater map and saves it in this->groundWaterMap. It
    // returns this->groundWaterMap.
    double *generateGroundWaterMap(
        // The width and height of the groundWaterMap to be generated
        // (and the input maps).
        unsigned width,
        unsigned height,
        // The normalized heightmap
        double *heightmap,
        // An array of bools which is populated by true for places
        // where there is water and false for places where there
        // isn't a river
        bool *waterMap,
        // A normalized map which signifies the heat at each position
        double *heatMap,
        // Whether to overwrite the old this->groundWaterMap
        bool overwriteOldMap = true);

    double *groundWaterMap;
private:
    FractalNoiseGenerator fractalNoiseGenerator;

    // Generates a new fractal noise map with
    // this->fractalNoiseGenerator of the speciefied size. It returns
    // this->fractalNoiseGenerator.noiseMap. The returned array
    // shouldn't be deleted, since it will be reused for subsequent
    // noise maps.
    double *getNoiseMap(
        // The width and height of the required noiseMap
        unsigned width,
        unsigned height);

    // Returns a groundWater value for a given point.
    double getGroundWaterValue(
        // The x and y coordinates of the point
        unsigned x,
        unsigned y,
        // The width and height of the maps
        unsigned width,
        unsigned height,
        // The maps on which the point lays
        double *heightmap,
        bool *waterMap,
        double *heatMap,
        double *noiseMap);

    // Returns a water score based on how close the point is to water
    double getWaterScore(
        // The position of the point
        unsigned x,
        unsigned y,
        // The size of the waterMap
        unsigned width,
        unsigned height,
        bool *waterMap);

    // Returns the distance the point is from the closest water point
    double getWaterDistance(
        // The position of the point
        unsigned x,
        unsigned y,
        // The size of the waterMap
        unsigned width,
        unsigned height,
        bool *waterMap);


    bool firstMap;
    unsigned int previousWidth, previousHeight;
};
